로딩 중이에요... 🐣
[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
1. 모델필드 옵션 | ✅ 저자: 이유정(박사)
- 개념: 데이터베이스(DB)에서 NULL 값을 허용할지 여부. 즉 데이터가 비어있어도 허용하겠다는 뜻.
- 영향:
null=True
이면 DB에서NULL
값을 허용하는 컬럼 생성됨. - 적용 예시:
DateField
,IntegerField
등 숫자형/날짜형 필드에 사용.
필드 타입 | 빈 값 처리 방법 | 필수 옵션 설명 |
---|---|---|
CharField |
빈 문자열 "" |
blank=True |
TextField |
빈 문자열 "" |
blank=True |
IntegerField |
빈 값은 None |
null=True , blank=True 둘다 필요 |
DateField |
빈 값은 None |
null=True , blank=True 필요 필요 |
BooleanField |
빈 값은 None |
null=True 사용해야 "선택 없음" 허용 가능 |
- 개념: 폼(Form) 유효성 검사 시 빈 값을 허용할지 여부.
- 영향:
blank=True
면form.is_valid()
체크 시 빈 입력 허용됨. - 적용 예시: 사용자가 필드를 안 채워도 오류가 나지 않음.
- 개념:
CharField
,EmailField
등 문자 필드의 최대 입력 길이 설정. - 영향: DB에는
VARCHAR(n)
으로 설정됨 + 폼에서maxlength
제약 반영.
- 개념: 사용자가 값을 입력하지 않았을 때 자동으로 채워줄 기본값을 지정하는 옵션
- 영향: 객체 생성 시 해당 필드가 비어 있어도 자동 채워짐.
필드 타입 | 예시 코드 | 설명 |
---|---|---|
CharField |
name = models.CharField <br>(..., default="익명") |
문자열 기본값 지정 |
IntegerField |
age = models.IntegerField <br>(..., default=0) |
숫자형 기본값 |
BooleanField |
is_open = models.BooleanField <br>(default=True) |
True/False 기본값 |
DateField |
birth = models.DateField <br>(default=date.today) |
날짜 기본값 (함수 사용도 가능) |
DateTimeField |
created = models.DateTimeField<br>(default=timezone.now) |
현재시간 기본값 |
TextField |
bio = models.TextField<br>(default="자기소개 없음") |
긴 문자열도 가능 |
FloatField |
rating = models.FloatField<br>(default=0.0) |
소수형 기본값 |
EmailField |
email = models.EmailField <br>(default="no@none.com") |
이메일 기본값 |
ImageField |
photo = models.ImageField <br>(default="default.jpg") |
초기 이미지 경로 |
SlugField |
slug = models.SlugField <br>(default="default-slug") |
URL-friendly slug 기본값 |
UUIDField |
uuid = models.UUIDField<br>(default=uuid.uuid4) |
UUID 기본값 (동적 함수도 가능) |
- 개념: 정해진 몇 가지 값 중 하나만 넣을 수 있게 제한하는 역할.
- 영향: Admin/Form에서는 드롭다운 박스로 나타남, DB에는 실제 키만 저장됨.
- S,M,L은 실제 DB에 저장되는 값.
- 이 필드를 호출하면 자동으로 드롭다운 메뉴가 생성됨.
- 개념: 해당 필드에 DB 인덱스 생성 → 조회 속도 향상.
- 영향: 필터링, 검색 등에 자주 사용되는 필드에 지정.
- 인덱스가 없을 때는 DB가 모든 행을 처음부터 끝까지 다 뒤지는 “풀스캔”을 합니다.
db_index=True
로 인덱스를 설정하면, 정렬된 인덱스를 활용해 “전화번호 범위”처럼 조건이 있는 검색도 빠르게 처리할 수 있습니다.
- 개념: 해당 값이 유일해야 함을 보장.
- 영향: DB에서
UNIQUE
제약조건 추가됨. 중복 저장 시 오류 발생. unique=True
는 "이 필드 값이 중복되면 안 된다"는 제약을 주는 옵션입니다.
- 개념: 해당 필드를 기본 키(PK)로 지정.
- 영향:
id
필드가 자동 생성되지 않고, 지정된 필드가 PK 역할 수행. - id 대신 다른 필드를 기본 키로 쓰고 싶을 때 사용함
- 예시: 도서 ISBN 번호. 국가 코드 (ISO), 학생 학번, 주문 번호 (UUID 사용)
- 이런 상황에서는
id
필드 없이도 그 자체로 유일함을 보장하는 값이 존재하므로primary_key=True
를 지정합니다.
- 개념: Admin/Form에서 수정 불가 상태로 만듦.
- 영향: 관리자 화면에서 입력칸이 아예 표시되지 않음.
# 주문 번호는 시스템이 자동으로 생성하므로, 관리자가 수정하면 안 됨
order_code = models.CharField(max_length=20, editable=False)
# 글 작성자를 로그인된 사용자로 자동 지정 → 폼에서 보여줄 필요 없음
created_by = models.ForeignKey(User, editable=False, on_delete=models.CASCADE)
# 상품 수량 × 단가 등으로 계산되는 값 → 직접 입력받지 않음
total_price = models.IntegerField(editable=False)
# 관리자가 수정할수록 증가하는 수치 → 직접 수정 금지
edit_count = models.IntegerField(default=0, editable=False)
- 개념: 폼 필드 아래에 설명 텍스트를 보여줌.
- 영향: 관리자, 사용자 폼에서 입력 도움말로 사용됨.
# 입력자에게 정확한 형식을 안내
phone = models.CharField(max_length=20, help_text="010-1234-5678 형식으로 입력하세요.")
# 이미지 용량/확장자 제한을 사용자에게 미리 알려줌
profile_image = models.ImageField(upload_to="profile", help_text="500KB 이하의 JPG 이미지만 업로드 가능")
# 비밀번호 규칙을 친절하게 설명
password = models.CharField(max_length=128, help_text="8자 이상, 숫자와 특수문자를 포함하세요.")
# 생략해도 되는 필드라는 걸 설명
nickname = models.CharField(max_length=30, blank=True, help_text="입력하지 않으면 기본 이름이 사용됩니다.")
- 개념: 필드의 화면상 라벨 표시 이름을 지정.
- 영향: Admin, 폼, 에러 메시지 등에 이 이름이 사용됨.
verbose_name
을 직접 지정하지 않으면 Django는 모델 클래스 이름을 단어로 분리하고 소문자로 바꾼 후verbose_name_plural
도 기본적으로 자동 복수형으로 변환해서 사용
verbose_name을 사용한 예시
사용하지 않은 예시
- 개념: DB에서 사용할 실제 컬럼 이름을 지정.
- 영향: 마이그레이션 시 해당 이름으로 컬럼 생성됨.
db_column
옵션은 Django 모델의 필드 이름과 실제 데이터베이스의 컬럼 이름을 다르게 하고 싶을 때 사용하는 옵션입니다.- 이런 필드 옵션은 모델 정의부에서 설정해야 실제 필드 호출시에도 적용될수 있습니다.
- 개념: 입력 값의 유효성 검사를 위한 검사 함수 목록 지정.
- 영향:
full_clean()
또는form.is_valid()
시 실행됨. 조건 불만족 시ValidationError
.
# Django에서 모델과 유효성 검사 도구들을 불러옴
from django.db import models
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator, RegexValidator
# 입력 값이 20 이상, 40 이하가 아니면 저장 불가
age = models.IntegerField(validators=[MinValueValidator(20), MaxValueValidator(40)])
# 정규식 검사: +로 시작할 수 있고, 그 뒤에 숫자 9~15자리여야 함
phone_number = models.CharField(max_length=15, validators=[RegexValidator(r'^\+?\d{9,15}$')])
정규식표현:
r''
: Raw 문자열: 백슬래시()를 이스케이프 처리 없이 그대로 해석하도록 함
^
: 문자열의 시작을 의미
\+?
: + 기호가 있을 수도, 없을 수도 있음 (?는 0개 또는 1개)
\d{9,15}
: 숫자(digit)가 9자리 이상, 15자리 이하여야 함
$
: 문자열의 끝을 의미
- 개념:
validate_age
처럼 직접 작성한 검사 함수를 필드에 연결. - 영향: 값이 유효하지 않으면 오류 메시지 출력됨.
def validate_age(value):
if not 20 <= value <= 40:
raise ValidationError('나이는 20에서 40세 사이여야 합니다.')
value
: 모델 필드에 입력되는 실제 값입니다.20 <= value <= 40
조건을 만족하지 않으면,ValidationError
예외를 발생시켜 폼/관리자 화면에서 오류 메시지를 보여줍니다. 즉, 나이는 20세 이상 40세 이하만 허용된다는 의미입니다.
- 개념: DB 레벨에서 기본값을 직접 계산해 저장하도록 지정.
- 차이점:
default
는 파이썬에서 기본값 설정,db_default
는 DB에서 수행. - 예시:
db_default=Now()
→ DB가 현재 시간으로 자동 설정
created = models.DateTimeField(default=timezone.now)
- 이 경우 Django 서버가
timezone.now()
를 미리 호출해서created
필드에 값을 채워서 INSERT 함. 즉, Python 코드 실행 시점의 시간이 저장됨.
새로운 방식 (db_default=Now()
)
from django.db.models.functions import Now
created = models.DateTimeField(db_default=Now())
- 이 경우 Django는 INSERT 시 created 값을 생략하고,
- DB가 알아서
DEFAULT CURRENT_TIMESTAMP
로 채움. 즉, DB가 "지금"이라고 판단하는 시간을 직접 넣습니다. - 외부에서 DB에 직접 insert 하는 경우 Django 없이 DB에서 직접 데이터를 넣어도
db_default=Now()
는 자동으로 "지금 시간"을 넣어줍니다. - 정리하면
created_at
필드는db_default=Now()
라고 설정되어 있습니다. - 이 말은: “created_at을 내가 직접 넣지 않으면, DB가 지금 시간을 자동으로 채워줘” 라는 의미입니다.